package com.flowable.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.flowable.common.constant.FlowableConstant;
import com.flowable.common.result.CommonResult;
import com.flowable.converter.XmlConverter;
import com.flowable.service.GroupService;
import com.flowable.service.ProcDefService;
import org.flowable.engine.RepositoryService;
import org.flowable.engine.repository.Deployment;
import org.flowable.engine.repository.ProcessDefinition;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Map;

/**
 * 流程定义 实现
 */
@Service
public class ProcDefServiceImpl implements ProcDefService {

    @Autowired
    private RepositoryService repositoryService;

    @Autowired
    private GroupService groupService;

    @Autowired
    private XmlConverter xmlConverter;

    /**
     * 手动部署
     *
     * @param xml_name bpmn.xml文件名
     * @param name     流程定义名
     */
    @Override
    public CommonResult manualDeploy(String xml_name, String name) {
        Deployment deploy = null;
        try {
            deploy = repositoryService.createDeployment()
                    .addClasspathResource(xml_name)
                    .name(name)
                    .deploy();
        } catch (Exception e) {
            CommonResult.failed(e.getMessage());
        }
        if (deploy == null) {
            CommonResult.failed("deploy is null");
        }
        String deployId = deploy.getId();
        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
                .deploymentId(deployId)
                .singleResult();
        // 查找所有collection对应值
        Map<String, String> collectionMap = xmlConverter.getCollectionMap(processDefinition.getId());
        // 创建组
        JSONObject groupJsonObject = new JSONObject();
        JSONArray groupJsonArray = new JSONArray();
        groupJsonObject.put("group", groupJsonArray);
        collectionMap.forEach((k, v) -> {
            String inputValue = v.substring(k.length() + 1);
            // groupId = processDefinitionKEey:userTaskId
            String groupId = processDefinition.getKey() + FlowableConstant.COLON + k;
            String[] split = inputValue.split(FlowableConstant.UNDERLINE);
            String groupName = split[0];
            String groupType = split.length >= 2 ? split[1] : split[0];
            int version = processDefinition.getVersion();
            // 添加或修改 组
            CommonResult groupResult = groupService.modifyGroup(groupId, groupName, groupType, version);
            JSONObject groupData = (JSONObject) groupResult.getData();
            groupJsonArray.add(groupData);
        });

        // 查询 流程定义
        CommonResult commonResult = procDefQuery(deployId);
        JSONObject data = (JSONObject) commonResult.getData();
        data.put("deployName", deploy.getName());
        data.putAll(groupJsonObject);
        return CommonResult.success(data);
    }

    /**
     * 查询 流程定义
     */
    @Override
    public CommonResult procDefQuery(String deployId) {
        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
                .deploymentId(deployId)
                .singleResult();
        JSONObject jsonObject = new JSONObject();
        if (processDefinition == null) {
            return CommonResult.failed("processDefinition is null");
        }
        jsonObject.put("deployId", processDefinition.getDeploymentId());
        jsonObject.put("procDefId", processDefinition.getId());
        jsonObject.put("procDefName", processDefinition.getName());
        jsonObject.put("procDefDescription", processDefinition.getDescription());
        return CommonResult.success(jsonObject);
    }

    /**
     * 删除 流程定义
     *
     * @param deployId deploymentId
     * @param cascade  cascade=false||null   如果部署的流程启动了，不允许删除
     *                 cascade=true          级联删除，如果流程启动了，相关的任务一并会被删除
     */
    @Override
    public CommonResult procDefDelete(String deployId, boolean cascade) {
        try {
            repositoryService.deleteDeployment(deployId, cascade);
        } catch (Exception e) {
            return CommonResult.failed(e.getMessage());
        }
        return CommonResult.success("删除成功");
    }
}
